# coding=utf-8
from core import HackingTool
from core import HackingToolsCollection
from tools.webattack import Web2Attack

from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.text import Text
from rich.prompt import Prompt

console = Console()
PURPLE_STYLE = "bold magenta"


class RouterSploit(HackingTool):
    TITLE = "RouterSploit"
    DESCRIPTION = "The RouterSploit Framework is an open-source exploitation " \
                  "framework dedicated to embedded devices"
    INSTALL_COMMANDS = [
        "sudo git clone https://github.com/threat9/routersploit.git",
        "cd routersploit && sudo python3 -m pip install -r requirements.txt"
    ]
    RUN_COMMANDS = ["cd routersploit && sudo python3 rsf.py"]
    PROJECT_URL = "https://github.com/threat9/routersploit"


class WebSploit(HackingTool):
    TITLE = "WebSploit"
    DESCRIPTION = "Websploit is an advanced MITM framework."
    INSTALL_COMMANDS = [
        "sudo git clone https://github.com/The404Hacking/websploit.git;cd websploit/Setup;sudo chmod +x install.sh && sudo bash install.sh"
    ]
    RUN_COMMANDS = ["sudo websploit"]
    PROJECT_URL = "https://github.com/The404Hacking/websploit "


class Commix(HackingTool):
    TITLE = "Commix"
    DESCRIPTION = "Automated All-in-One OS command injection and exploitation " \
                  "tool.\nCommix can be used from web developers, penetration " \
                  "testers or even security researchers\n in order to test " \
                  "web-based applications with the view to find bugs,\n " \
                  "errors or vulnerabilities related to command injection " \
                  "attacks.\n Usage: python commix.py [option(s)]"
    INSTALL_COMMANDS = [
        "git clone https://github.com/commixproject/commix.git commix",
        "cd commix;sudo python setup.py install"
    ]
    RUN_COMMANDS = ["sudo python commix.py --wizard"]
    PROJECT_URL = "https://github.com/commixproject/commix"

    def __init__(self):
        super(Commix, self).__init__(runnable=False)


class ExploitFrameworkTools(HackingToolsCollection):
    TITLE = "Exploit framework"
    TOOLS = [
        RouterSploit(),
        WebSploit(),
        Commix(),
        Web2Attack()
    ]

    def _get_attr(self, obj, *names, default=""):
        for n in names:
            if hasattr(obj, n):
                return getattr(obj, n)
        return default

    def pretty_print(self):
        table = Table(title="Exploit framework", show_lines=True, expand=True)
        table.add_column("Title", style="magenta", no_wrap=True)
        table.add_column("Description", style="magenta")
        table.add_column("Project URL", style="magenta", no_wrap=True)

        for t in self.TOOLS:
            title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
            desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="")
            url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
            table.add_row(str(title), str(desc).strip().replace("\n", " "), str(url))

        panel = Panel(table, title=f"[magenta]Available Tools[/magenta]", border_style=PURPLE_STYLE)
        console.print(panel)

    def show_options(self, parent=None):
        console.print("\n")
        console.print(Panel.fit(
            "[bold magenta]Exploit Framework Collection[/bold magenta]\n"
            "Select a tool to view options or run it.",
            border_style=PURPLE_STYLE
        ))

        table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
        table.add_column("Index", justify="center", style="bold yellow")
        table.add_column("Tool Name", justify="left", style="bold green")
        table.add_column("Description", justify="left", style="white")

        for i, tool in enumerate(self.TOOLS):
            title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
            desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
            table.add_row(str(i + 1), title, desc or "—")

        table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
        console.print(table)

        try:
            choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
            choice = int(choice)
            if 1 <= choice <= len(self.TOOLS):
                selected = self.TOOLS[choice - 1]
                # If tool exposes show_options (collection-style), delegate to it
                if hasattr(selected, "show_options"):
                    selected.show_options(parent=self)
                # Otherwise, if runnable, call its run method
                elif hasattr(selected, "run"):
                    selected.run()
                else:
                    console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
            elif choice == 99:
                return 99
        except Exception:
            console.print("[bold red]Invalid choice. Try again.[/bold red]")
        return self.show_options(parent=parent)


# --- Optional helper: pretty-print the tools list into a magenta-styled table.
# This helper is non-invasive and does not change tool logic.
def render_tools_table(tools, title: str | None = None):
    """
    Render a list of HackingTool instances (or objects with TITLE/DESCRIPTION/PROJECT_URL)
    as a rich table in magenta style.
    """
    tbl = Table(title=title or "Tools", show_lines=False, header_style=PURPLE_STYLE)
    tbl.add_column("Name", style=PURPLE_STYLE, no_wrap=True)
    tbl.add_column("Description")
    tbl.add_column("Project URL", overflow="fold")

    for t in tools:
        name = getattr(t, "TITLE", "<unknown>")
        desc = getattr(t, "DESCRIPTION", "")
        url = getattr(t, "PROJECT_URL", "")
        tbl.add_row(name, desc, url)

    console.print(Panel(tbl, border_style=PURPLE_STYLE, title=Text(title or "Toolset", style=PURPLE_STYLE)))


if __name__ == "__main__":
    tools = ExploitFrameworkTools()
    tools.pretty_print()
    tools.show_options()
